package main

import (
	"azfirewall-gateway/data"
	"azfirewall-gateway/gateway"
	"azfirewall-gateway/manage"
	"azfirewall-gateway/service"
	"azfirewall-gateway/utils"
	"crypto/tls"
	"flag"
	"fmt"
	"github.com/sirupsen/logrus"
	"net"
	"net/http"
	"os"
	"runtime"
)

func main() {
	ver := flag.Bool("version", false, "Display Version Information")
	flag.Parse()
	if *ver {
		fmt.Println(data.Version)
		os.Exit(0)
	}
	_ = os.Setenv("GODEBUG", os.Getenv("GODEBUG")+",tls13=1")
	//_ = os.Setenv("GOPROXY", "https://goproxy.io,direct")
	runtime.GOMAXPROCS(runtime.NumCPU())
	utils.MainLog.SetFormatter(&logrus.TextFormatter{
		ForceColors:               true,
		DisableColors:             false,
		EnvironmentOverrideColors: false,
		DisableTimestamp:          false,
		FullTimestamp:             true,
		TimestampFormat:           "2006-01-02 15:04:05",
		DisableSorting:            false,
		SortingFunc:               nil,
		DisableLevelTruncation:    false,
		QuoteEmptyFields:          false,
		FieldMap:                  nil,
		CallerPrettyfier:          nil,
	})
	utils.MainLog.SetLevel(logrus.DebugLevel)
	utils.MainLog.Info("StarhomeWebFirewall v" + data.Version + " 启动中 ...\n")
	if utils.MainLog.GetLevel() == logrus.DebugLevel {
		utils.MainLog.Warn("防火墙正在正在DEBUG模式运行！")
	}
	data.InitData()
	utils.MainLog.Info("StarhomeWebFirewall 已全部准备就绪！")
	utils.MainLog.Info("---【程序正在运行】---")
	tlsconfig := &tls.Config{
		GetCertificate: func(info *tls.ClientHelloInfo) (certificate *tls.Certificate, err error) {
			cert, err := service.GetCertByDomain(info.ServerName)
			return cert, err
		},
		NextProtos: []string{"h2", "http/1.1"},
		MinVersion: tls.VersionTLS11,
		CipherSuites: []uint16{
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
			tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
			tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
	}
	manageAPIServer := http.NewServeMux()
	manageAPIServer.HandleFunc("/", manage.DefaultManageView)
	manageAPIServer.HandleFunc("/v1/api", manage.APIHandler)
	go func() {
		listener, _ := net.Listen("tcp", data.CFG.AdminHTTPListen)
		err := http.Serve(listener, manageAPIServer)
		utils.CheckError("尝试监听管理端口时遇到错误：", err)
	}()
	mainGateway := http.NewServeMux()
	mainGateway.HandleFunc("/", gateway.ReverseProxyHandler)
	go func() {
		listener, _ := net.Listen("tcp", ":80")
		l := http.Serve(listener, AddContextHandler(mainGateway))
		utils.CheckError("尝试监听端口80过程中发生错误：", l)
	}()
	listener, _ := tls.Listen("tcp", ":443", tlsconfig)
	l := http.Serve(listener, AddContextHandler(mainGateway))
	utils.CheckError("尝试监听端口443过程中发生错误：", l)
}
func AddContextHandler(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		next.ServeHTTP(w, r)
	})
}
